/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.isystem.autpart.controller;

import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.isystem.autpart.beans.TControlRol;
import org.isystem.autpart.beans.TCuenta;
import org.isystem.autpart.beans.TEmpleado;
import org.isystem.autpart.beans.TPersona;
import org.isystem.autpart.beans.TPersonaJuridica;
import org.isystem.autpart.beans.TPersonaNatural;
import org.isystem.autpart.beans.TRol;
import org.isystem.autpart.beans.TSucursal;
import org.isystem.autpart.dao.DAO;
import org.isystem.autpart.util.RandomStringGenerator;
import org.isystem.autpart.util.idNew;
import org.zkoss.bind.ValidationContext;
import org.zkoss.bind.Validator;
import org.zkoss.bind.annotation.BindingParam;
import org.zkoss.bind.annotation.Command;
import org.zkoss.bind.annotation.Init;
import org.zkoss.bind.annotation.NotifyChange;
import org.zkoss.bind.validator.AbstractValidator;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.util.Clients;
import org.zkoss.zk.ui.util.GenericForwardComposer;
//import org.zkoss.zul.ListModelList;

/**
 *
 * @author miguel
 */
public class ManagerAdmUsuario extends GenericForwardComposer {

    private static final long serialVersionUID = 1L;
    private List<TCuenta> cuentas;
    private List<TSucursal> sucursales;
    private List<TRol> roles;
    private List<TControlRol> controlRoles;
    private TCuenta cuenta = new TCuenta();
    private TControlRol controlRol = new TControlRol();
    private TSucursal sucursalSelected = new TSucursal();
    private TRol rolSelected = new TRol();
    private TCuenta cuentaSelected = new TCuenta();
    private boolean mostrarAddUS;
    private boolean mostrarControlRol;
    private boolean mostrarAsignarRol;
    private boolean verSave;
    private String saveLabel = "";
    private String tipoP = "N";
    private DAO dao = new DAO();
    private String captchaInput;
    private String captcha;
    private String buscar ="";
    private String val;
    private String val1;
    
    private Session s;
    //Validators
    private Validator pasValidator;
    private Validator captchaValidator;
    
    //validation messages
    Map<String, String> validationMessages = new HashMap<String,String>();
    
    //regenrerador
    private RandomStringGenerator rsg = new RandomStringGenerator(4);

    @NotifyChange({"cuenta"})
    public Validator getPasValidator() {
        return new AbstractValidator() {
            
            public void validate(ValidationContext ctx) {
                String val = (String)ctx.getProperties("contraseniaRepe")[0].getValue();
                System.out.println("validator "  + val);
                try{
                    if (!val.equals(cuenta.getContraseniaVista())){
                        System.out.println("error " + cuenta.getContraseniaVista()+ " <> " + val);
                        validationMessages.put("repassTextBox", "Contraseñas no coinciden");
                        ctx.setInvalid(); // mark invalid
                    }else{
                        validationMessages.remove("repassTextBox");
                    }
                }catch (Exception e){
                    validationMessages.put("repassTextBox", "no permitido");
                        ctx.setInvalid();
                }
                ctx.getBindContext().getBinder().notifyChange(validationMessages, "repassTextBox");                    
            }
        };
    }
    
    @NotifyChange({"captcha"})
    public Validator getCaptchaValidator() {
        return new AbstractValidator() {
            
            public void validate(ValidationContext ctx) {
                String val = (String)ctx.getProperties("captchaInput")[0].getValue();
                System.out.println(captcha + " validator "  + val);
                if(val == null || !captcha.equals(val)) {
                    validationMessages.put("captcha", "Incorrecto");
                    ctx.setInvalid(); // mark invalid
                }else{
                    validationMessages.remove("captcha");
                }
                ctx.getBindContext().getBinder().notifyChange(validationMessages, "captcha");                    
            }
        };
    }
    
    public Validator getFormValidatorUs(){
        System.out.println("afuera");
        return new AbstractValidator() {
//            private HashMap validationMessages;

            public void validate(ValidationContext ctx) {
// Consultar si es persona natural o juridica
                String val = (String)ctx.getProperties("usuario")[0].getValue();
                System.out.println("validator "  + val);
//                ValidationMessages vmsgs = (ValidationMessages) ctx.getValidatorArg("vmsgs");
//                validationMessages.put("usuarioTextBox", "value1 error");
//                ctx.setInvalid(); // mark invalid
//                ValidationMessages vmsgs = ((BinderCtrl)ctx.getBindContext().getBinder()).getValidationMessages();
//                addInvalidMessage(ctx, "usuario", "value1 error");
//                System.out.println("111");
//                ctx.getBindContext().getBinder().notifyChange(validationMessages, "usuarioTextBox");
//                if(invalidCondition01(val)){
//                    addInvalidMessage(ctx, "fkey1", "value1 error");
//                }
//                val = (String)ctx.getProperties("value2")[0].getValue();
//                if(invalidCondition02(val)){
//                    addInvalidMessage(ctx, "fkey2", "value2 error");
//                }
//                val = (String)ctx.getProperties("value3")[0].getValue();
//                if(invalidCondition03(val)){
//                    addInvalidMessage(ctx, "fkey3", "value3 error");
//                }
//                ctx.getBindContext().getBinder().notifyChange(validationMessages, "usuarioTextBox");
                
                
            }
        };
    }
    
//    @NotifyChange({"mostrarAddUS", "tipoP", "cuentas", "cuentaSelected", "modelCuentas"})
        @Init
        public void init() {
            cuentaSelected.setTEmpleado(new TEmpleado());
            cuentaSelected.getTEmpleado().setTPersona(new TPersona());
            cuentaSelected.getTEmpleado().getTPersona().setTPersonaNatural(new TPersonaNatural());
            cuentaSelected.getTEmpleado().getTPersona().setTPersonaJuridica(new TPersonaJuridica());
            System.out.println("onCreatewinAdmUs");
            s = dao.getSession();
            actualizaListaUsuario(s, "");
            actualizaListaSucursal(s);
            mostrarAddUS = false;
            mostrarControlRol = false;
            mostrarAsignarRol = false;
            captcha = rsg.getRandomString();
        }

    
    @Command
    @NotifyChange({"captcha","captchaInput"})
    public void regenerate() {
        captcha = rsg.getRandomString();
        captchaInput = "";
    }
    
    
    @NotifyChange({"verSave","cuenta","mostrarAddUS","saveLabel","val"})
    @Command()
    public void onClickaddUs() {
        cuenta = new TCuenta();
        cuenta.setTEmpleado(new TEmpleado());
        cuenta.getTEmpleado().setTPersona(new TPersona());
        sucursalSelected = new TSucursal();
        mostrarAddUS = true;
        mostrarControlRol = false;
        mostrarAsignarRol = false;
        verSave = true;
        saveLabel ="Guardar";
        val="";
        cuenta.getTEmpleado().getTPersona().setTPersonaNatural(new TPersonaNatural());
        cuenta.getTEmpleado().getTPersona().setTPersonaJuridica(new TPersonaJuridica());
    }
    
    @Command
    @NotifyChange({"cuentas", "buscar","mostrarAddUS"})
    public void onClickSearch() {
        System.out.println("click search");
        actualizaListaUsuario(s, " where t.usuario like '%"+buscar+"%'");
    }
    
    @NotifyChange({"cuenta","mostrarAsignarRol","roles","rolSelected"})
    @Command()
    public void onClickAR() {
        controlRol = new TControlRol();
        controlRol.setTCuenta(cuenta);
        controlRol.setTRol(new TRol());
        rolSelected = new TRol();
        mostrarAddUS = false;
        mostrarControlRol = false;
        mostrarAsignarRol = true;
        actualizaListaRoles(s,"");
        val1="";
    }
    
    @Command
    @NotifyChange({"tipoP"})
    public void onCheckTipoP() {
        System.out.println("tipo " +tipoP);
    }
    

    @NotifyChange({"cuenta","verSave","cuentas","captchaInput","val","mostrarControlRol"})
    @Command()
    public void guardaUsuario() {
        // consultar si es persona natural o juridica

        if (saveLabel.equals("Guardar")){
            //Asignacion de IDs
//            dao = new DAOGeneral();
            cuenta.setId(idNew.id());
            cuenta.getTEmpleado().setId(idNew.id());
            cuenta.getTEmpleado().getTPersona().setId(idNew.id());
            cuenta.setEnabled(true);
            cuenta.setContrasenia(dao.md5(s, cuenta.getContraseniaVista()));
            
            if (tipoP.equals("N")){
                cuenta.getTEmpleado().getTPersona().getTPersonaNatural().setId(idNew.id());
                cuenta.getTEmpleado().getTPersona().setTPersonaJuridica(null);
            }else{
                cuenta.getTEmpleado().getTPersona().getTPersonaJuridica().setId(idNew.id());
                cuenta.getTEmpleado().getTPersona().setTPersonaNatural(null);
            }
        }else{
            if ((!cuenta.getContraseniaVista().equals("/////"))){
                String contrasenia = dao.md5(s, cuenta.getContraseniaVista());
                if ((!(contrasenia.equals(cuenta.getContrasenia()))) ) {
                    cuenta.setContrasenia(contrasenia);
                }
            }
            if (tipoP.equals("N")){
                cuenta.getTEmpleado().getTPersona().setTPersonaJuridica(null);
            }else{
                cuenta.getTEmpleado().getTPersona().setTPersonaNatural(null);
            }
        }
        
        cuenta.getTEmpleado().setTSucursal(sucursalSelected);
        if ((val.equals("")) && (cuenta.getTEmpleado().getTSucursal()== null)){
            cuenta.getTEmpleado().setTSucursal(null);
        }else if ((val.equals("")) && (cuenta.getTEmpleado().getTSucursal().getId() == null)){
            cuenta.getTEmpleado().setTSucursal(null);
        }
        Transaction tr = s.beginTransaction();
        try{
            tr.begin();
            dao.persist(s,cuenta);
            tr.commit();
        }catch (HibernateException e){
            System.out.println("error " + e.getMessages());
            tr.rollback();
            return;
        }
        
        verSave = false;
        actualizaListaUsuario(s, "");
        captchaInput = "";
        System.out.println("es");
        mostrarControlRol = false;
        mostrarAddUS = false;
        return;
    }
    
    @NotifyChange({"controlRol","val1","mostrarControlRol","controlRoles"})
    @Command()
    public void guardaCR() {
        // consultar si es persona natural o juridica

        //Asignacion de IDs
//        TControlRol crModi = new TControlRol();
        Transaction tr = s.beginTransaction();
        try{
            TControlRol crModi = (TControlRol) dao.findOne(s, "from TControlRol cr where cr.TCuenta.id = '" + 
                      cuenta.getId() + "' and cr.estado = 'A'" );
            tr.begin();
            crModi.setEstado("I");
            dao.update(s, crModi);
            tr.commit();
        }catch (Exception e){
            tr.rollback();
        }
//        if (existeAnterior){
////            TControlRol tcr = new TControlRol();
//            TControlRol tcr = (TControlRol) dao.load(TControlRol.class, crModi.getId()+"");
//            tcr.setEstado("I");
//            dao.update();
//        }
        controlRol.setId(idNew.id());
        controlRol.setEstado("A");
        controlRol.setFechaInicio(new Date());
        controlRol.setTRol(rolSelected);
        tr = s.beginTransaction();
        tr.begin();
        dao.persist(s,controlRol);
        tr.commit();
        actualizaListaControRoles(s, " where cr.TCuenta.id = '"+cuenta.getId() +"'");
//        dao.Close();
        System.out.println("es");
        mostrarControlRol = false;
        mostrarAddUS = false;
        return;
    }
    
    
    @NotifyChange({"verSave","cuenta","mostrarAddUS","saveLabel","tipoP", "val","mostrarControlRol","sucursalSelected"})
    @Command()
    public void editaUsuario(@BindingParam("cuent") TCuenta cuent ) {
        System.out.println("aqui editar");
//        dao = new DAOGeneral();
        verSave = true;
        cuenta = (TCuenta) dao.load(s, TCuenta.class, cuent.getId()+"");
        cuenta.setContraseniaVista("/////");
        cuenta.setContraseniaRepe("/////");
        sucursalSelected = cuenta.getTEmpleado().getTSucursal();
        mostrarAddUS = true;
        mostrarControlRol = false;
        saveLabel = "Modificar";
        val="";
        try {
            if (cuenta.getTEmpleado().getTPersona().getTPersonaNatural() != null) {
                tipoP = "N";
                cuenta.getTEmpleado().getTPersona().setTPersonaJuridica(new TPersonaJuridica());
            } else {
                tipoP = "J";
                cuenta.getTEmpleado().getTPersona().setTPersonaNatural(new TPersonaNatural());
            }
            
        } catch (Exception e) {
        }
//        dao.Close();
        return;
    }
    
    @NotifyChange({"cuentas","mostrarAddUS","saveLabel","mostrarControlRol"})
    @Command()
    public void eliminaUsuario(@BindingParam("cuent") TCuenta cuent ) {
//        dao = new DAOGeneral();
        cuenta = cuent;
        Transaction tr = s.beginTransaction();
        tr.begin();
        dao.delete(s, cuenta);
        tr.commit();
        mostrarAddUS = false;
        mostrarControlRol = false;
        
        actualizaListaUsuario(s, "");
//        dao.Close();
    }
    
    
    @NotifyChange({"verSave","cuenta","mostrarAddUS","tipoP","val","controlRoles","mostrarControlRol","sucursalSelected"})
    @Command()
    public void selecCuentas() {
        System.out.println("on select");
//        dao = new DAOGeneral();
        verSave = false;
        cuenta = cuentaSelected;
        sucursalSelected = cuenta.getTEmpleado().getTSucursal();
        mostrarAddUS = true;
        mostrarControlRol = true;
        actualizaListaControRoles(s, " where cr.TCuenta.id = '"+cuenta.getId() +"'");
        val = "";
        try {
            if (cuenta.getTEmpleado().getTPersona().getTPersonaNatural() != null) {
                tipoP = "N";
            } else {
                tipoP = "J";
            }
        } catch (Exception e) {
        }
//        dao.Close();
    }
    
    @Command()
    public void selecSucursal() {
        System.out.println("Selecciona Sucursal");
    }
    
    @Command()
    public void selecRol() {
        System.out.println("Selecciona Rol");
    }


    private void showNotify(String msg, Component ref) {
        Clients.showNotification(msg, "info", ref, "end_center", 2000);
    }

    public List<TCuenta> getCuentas() {
        return cuentas;
    }

    public void setCuentas(List<TCuenta> cuentas) {
        this.cuentas = cuentas;
    }

    public TCuenta getCuenta() {
        return cuenta;
    }

    public void setCuenta(TCuenta cuenta) {
        this.cuenta = cuenta;
    }

    public String getTipoP() {
        return tipoP;
    }

    public void setTipoP(String tipoP) {
        this.tipoP = tipoP;
    }

    public boolean isMostrarAddUS() {
        return mostrarAddUS;
    }

    public void setMostrarAddUS(boolean mostrarAddUS) {
        this.mostrarAddUS = mostrarAddUS;
    }

    public TCuenta getCuentaSelected() {
        return cuentaSelected;
    }

    public void setCuentaSelected(TCuenta cuentaSelected) {
        this.cuentaSelected = cuentaSelected;
    }

    private void actualizaListaUsuario(Session s, String sql) {
        cuentas = new LinkedList<TCuenta>();
        cuentas.clear();
        cuentas = dao.findAll(s, "from TCuenta t " + sql);
        for (TCuenta c : cuentas) {
            try {
                if (c.getTEmpleado().getTPersona().getTPersonaNatural() != null) {
                    c.getTEmpleado().setDocumento(c.getTEmpleado().getTPersona().getTPersonaNatural().getDni());
                    c.getTEmpleado().setNombre(c.getTEmpleado().getTPersona().getTPersonaNatural().getApellidos() + 
                            ", " + c.getTEmpleado().getTPersona().getTPersonaNatural().getNombres());
                } else {
                    c.getTEmpleado().setDocumento(c.getTEmpleado().getTPersona().getTPersonaJuridica().getRuc());
                    c.getTEmpleado().setNombre(c.getTEmpleado().getTPersona().getTPersonaJuridica().getRazonSocial());
                }
            } catch (Exception e) {
            }
        }
    }

    private void actualizaListaSucursal(Session s) {
        sucursales = new LinkedList<TSucursal>();
        sucursales.clear();
        sucursales = dao.findAll(s, "from TSucursal");
    }
    
    private void actualizaListaControRoles(Session s, String sql) {
        controlRoles = new LinkedList<TControlRol>();
        controlRoles.clear();
        controlRoles = dao.findAll(s, "from TControlRol cr" + sql);
    }
    
    private void actualizaListaRoles(Session s, String sql) {
        roles = new LinkedList<TRol>();
        roles.clear();
        roles = dao.findAll(s, "from TRol r" + sql);
    }

    public String getSaveLabel() {
        return saveLabel;
    }

    public void setSaveLabel(String saveLabel) {
        this.saveLabel = saveLabel;
    }

    public boolean isVerSave() {
        return verSave;
    }

    public void setVerSave(boolean verSave) {
        this.verSave = verSave;
    }

    public Map<String, String> getValidationMessages() {
        return validationMessages;
    }

    public void setValidationMessages(Map<String, String> validationMessages) {
        this.validationMessages = validationMessages;
    }

    public String getCaptchaInput() {
        return captchaInput;
    }

    public void setCaptchaInput(String captchaInput) {
        this.captchaInput = captchaInput;
    }

    public String getCaptcha() {
        return captcha;
    }

    public void setCaptcha(String captcha) {
        this.captcha = captcha;
    }

    public List<TSucursal> getSucursales() {
        return sucursales;
    }

    public void setSucursales(List<TSucursal> sucursales) {
        this.sucursales = sucursales;
    }

    public String getVal() {
        return val;
    }

    public void setVal(String val) {
        this.val = val;
    }

    public List<TControlRol> getControlRoles() {
        return controlRoles;
    }

    public void setControlRoles(List<TControlRol> controlRoles) {
        this.controlRoles = controlRoles;
    }

    public boolean isMostrarControlRol() {
        return mostrarControlRol;
    }

    public void setMostrarControlRol(boolean mostrarControlRol) {
        this.mostrarControlRol = mostrarControlRol;
    }

    public List<TRol> getRoles() {
        return roles;
    }

    public void setRoles(List<TRol> roles) {
        this.roles = roles;
    }

    public TControlRol getControlRol() {
        return controlRol;
    }

    public void setControlRol(TControlRol controlRol) {
        this.controlRol = controlRol;
    }

    public boolean isMostrarAsignarRol() {
        return mostrarAsignarRol;
    }

    public void setMostrarAsignarRol(boolean mostrarAsignarRol) {
        this.mostrarAsignarRol = mostrarAsignarRol;
    }

    public String getVal1() {
        return val1;
    }

    public void setVal1(String val1) {
        this.val1 = val1;
    }

    public String getBuscar() {
        return buscar;
    }

    public void setBuscar(String buscar) {
        this.buscar = buscar;
    }

    public TRol getRolSelected() {
        return rolSelected;
    }

    public void setRolSelected(TRol rolSelected) {
        this.rolSelected = rolSelected;
    }

    public TSucursal getSucursalSelected() {
        return sucursalSelected;
    }

    public void setSucursalSelected(TSucursal sucursalSelected) {
        this.sucursalSelected = sucursalSelected;
    }


}
